/**
 * @name Circle menu
 * @description Responsible for providing context menu functionality
 */

jt.module('CircleMenu', function(context) {
     
        // useful shorthands
        var canvas = context.canvas,
                settings = context.settings,
                gh = context.settings.grid.h,
                gv = context.settings.grid.v;
        
        /*
         *      Helper drawing arc function from one degree to another starting from (x,y) => x = R, y = 0;
         *      author: skowronkow@gmail.com
         */
         
        var getArcPath = function (x, y, fromDegree, toDegree, R) {
                
                // TODO: handle it
                if(Math.abs(toDegree - fromDegree) > 360)
                        return
                
                var sin = Math.sin,
                        cos = Math.cos,
                        abs = Math.abs,
                        pi = Math.PI,
                        fromRad = pi * fromDegree / 180,
                        toRad = pi * toDegree / 180,
                        fx = x + R * cos(fromRad),
                        fy = y + R * sin(fromRad),
                        tx = x + R * cos(toRad),
                        ty = y + R * sin(toRad),
                        path;
                
                if((toDegree - fromDegree) <= 180)
                        path = ['M',fx,fy,'a',R,R,0,0,1,tx-fx,ty-fy];
                else
                        path = ['M',fx,fy,'a',R,R,0,1,1,tx-fx,ty-fy + 0.01];
                        
                return path;
        },
        
        centerArcPos = function(sx, sy, degree, R, width, height) {
                
                var rad = Math.PI * degree / 180;
                
                return {
                        x: sx + R * Math.cos(rad) - width / 2,
                        y: sy + R * Math.sin(rad) - height / 2  
                }
        },
         
        /*
         *      Summary: CircleActions object definition
         *      Handles drawing and trigger proper circle action.
         */
        CircleActions = function(options) {
                        
                var options = util.extend({
                        circleRadius: 120,
                        actionImgWidth: 20,
                        actionImgHeight: 20
                }, options),
        
                attr = util.extend({
                        'stroke': "#000", 
                        'stroke-width': 40, 
                        'stroke-opacity': 0.3
                }, options && options.arcAttr || {}),
                
                onClickHandler = null,
                
                actionItemsContainer = null,
                actions = [],
                
                // shorthands
                
                r = options.circleRadius,
                iw = options.actionImgWidth,
                ih = options.actionImgHeight;
                
                var circles4 = canvas.set(
                        canvas.set(canvas.path(getArcPath(0, 0, 0, 90, r)), canvas.image('', centerArcPos(0,0,45,r,iw,ih).x, centerArcPos(0,0,45,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 90, 180, r)), canvas.image('', centerArcPos(0,0,135,r,iw,ih).x, centerArcPos(0,0,135,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 180, 270, r)), canvas.image('', centerArcPos(0,0,225,r,iw,ih).x, centerArcPos(0,0,225,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 270, 360, r)), canvas.image('', centerArcPos(0,0,315,r,iw,ih).x, centerArcPos(0,0,315,r,iw,ih).y, iw, ih)))
                .attr(attr)
                .hide();
                                        
                // Handle user actions (mouse events)
                for(var i = 0, len = circles4.length; i < len; i++) {
                                        
                        (function(arcItem, i) {
                                
                                arcItem.mouseover(function() {
                                        arcItem[0].animate({'stroke-opacity': 1}, 200, '>');
                                        arcItem[1].animate({'opacity': 1}, 200, '>').scale(1.6);
                                        context.event('showMouseTooltip', actions[i].action.name);
                                }).mouseout(function() {
                                        arcItem[0].animate({'stroke-opacity': attr['stroke-opacity']}, 200, '>');
                                        arcItem[1].animate({'opacity': 0.80}, 200, '>').scale(1/1.6);
                                        context.event('hideTooltip');
                                }).click(function() {
                                        context.event('hideTooltip');
                                        
                                        if(onClickHandler)
                                                onClickHandler(actions[i].action);

                                });
                        
                        })(circles4[i], i)
                }
                
                var circles8 = canvas.set(
                        canvas.set(canvas.path(getArcPath(0, 0, 0, 45, r)), canvas.image('', centerArcPos(0,0,27.5-5,r,iw,ih).x, centerArcPos(0,0,27.5-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 45, 90, r)), canvas.image('', centerArcPos(0,0,72.5-5,r,iw,ih).x, centerArcPos(0,0,72.5-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 90, 135, r)), canvas.image('', centerArcPos(0,0,117.5-5,r,iw,ih).x, centerArcPos(0,0,117-5.5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 135, 180, r)), canvas.image('', centerArcPos(0,0,162-5,r,iw,ih).x, centerArcPos(0,0,162-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 180, 225, r)), canvas.image('', centerArcPos(0,0,207.5-5,r,iw,ih).x, centerArcPos(0,0,207.5-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 225, 270, r)), canvas.image('', centerArcPos(0,0,252.5-5,r,iw,ih).x, centerArcPos(0,0,252.5-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 270, 315, r)), canvas.image('', centerArcPos(0,0,297.5-5,r,iw,ih).x, centerArcPos(0,0,297.5-5,r,iw,ih).y, iw, ih)),
                        canvas.set(canvas.path(getArcPath(0, 0, 315, 360, r)), canvas.image('', centerArcPos(0,0,342.5-5,r,iw,ih).x, centerArcPos(0,0,342.5-5,r,iw,ih).y, iw, ih)))
                .attr(attr)
                .hide();
                                        
                // Handle user actions (mouse events)
                for(var i = 0, len = circles8.length; i < len; i++) {
                                        
                        (function(arcItem, i) {
                        
                                arcItem.mouseover(function() {
                                        arcItem[0].animate({'stroke-opacity': 1}, 200, '>');
                                        arcItem[1].animate({'opacity': 1}, 200, '>').scale(1.6);
                                        context.event('showMouseTooltip', actions[i].action.name);
                                }).mouseout(function() {
                                        arcItem[0].animate({'stroke-opacity': attr['stroke-opacity']}, 200, '>');
                                        arcItem[1].animate({'opacity': 0.80}, 200, '>').scale(1/1.6);
                                        context.event('hideTooltip');
                                        
                                }).click(function() {
                                        context.event('hideTooltip');
                                        
                                        if(onClickHandler)
                                                onClickHandler(actions[i].action);
                                });
                        
                        })(circles8[i], i)
                }
                
                this.addAction = function(action, iconPath) {           
                        actions.push({
                                action: action,
                                icon: iconPath
                        });
                        return this;
                };
                
                this.clearActions = function() {
                        actions = [];
                };
                
                this.show = function(centerX, centerY) {
                        
                        actionItemsContainer = canvas.set();
                        
                        var ArcsRef = actions.length < 3 ? circles4 : circles8;
                        
                        for(var i = 0, len = actions.length; i < len; i++) {
                                
                                var actItem = ArcsRef[i];
                                actItem[1].attr({'src': actions[i].icon});
                                
                                actionItemsContainer.push(actItem);
                        }

                        actionItemsContainer.stop();
                        actionItemsContainer.show();
                        actionItemsContainer.attr({ transform: 't' + centerX + ',' + centerY + 's0.95 ' })
                                .animate({opacity: 0.75}, 300, '>')
                                .toFront();
                        
                };
                
                this.hide = function() {
                        
                        if(!actionItemsContainer)
                                return;
                        
                        actionItemsContainer.hide();
                };
                
                this.onAction = function(callback) {
                        onClickHandler = util.bind(callback, arguments.caller);
                };
                
        },
        
        ActionsHolder = new CircleActions();
        
        ActionsHolder.onAction(function(action) {
                if(typeof(action.execute) === 'function'){
                        setTimeout(action.execute, 200);
                }
        });
        
        return {
                
                events: {
                
                        /*
                         *      Summary: Initialize module event handler
                         */
                        init: function() {
                                context.log('[CircleActionsModule] init');
                        },
                        
                        showCircleActions: function(posX, posY, actions) {
                                
                                if(!util.isArray(actions))
                                        return;
                                        
                                for(var i = 0, len = actions.length; i < len; i++){
                                        var action = actions[i];
                                        if(action.icon && action.name && typeof(action.execute) === 'function')
                                                ActionsHolder.addAction(action, action.icon);
                                }
        
                                ActionsHolder.show(posX, posY);
                        },
                        
                        hideCircleActions: function() {
                                ActionsHolder.hide();
                                ActionsHolder.clearActions();
                        }
                }
        }
        
});